package com.sam.security.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sam.core.domain.Page;
import com.sam.core.util.StringUtils;
import com.sam.security.dao.SecurityDao;
import com.sam.security.domain.AsyncTreeNode;
import com.sam.security.domain.Authority;
import com.sam.security.domain.Menu;
import com.sam.security.domain.Permission;
import com.sam.security.domain.Resource;
import com.sam.security.domain.Role;
import com.sam.security.domain.User;
import com.sam.security.service.SecurityService;

/**
 * 权限模块业务实现
 * @project EMan
 * @author Sam
 * @version
 * @date Feb 17, 2009 10:28:18 AM
 */
@Service("securityService")
@Transactional
public class SecurityServiceImpl implements SecurityService, UserDetailsService {
	@javax.annotation.Resource(name = "securityJdbcDao")
	private SecurityDao securityDao;

	public void addAllRolePermission(String roleId, String menuId) {
		securityDao.deleteRolePermission(roleId, menuId);
		securityDao.addRolePermissionAll(roleId, menuId);
	}

	public void deleteAllRolePermission(String roleId, String menuId) {
		securityDao.deleteRolePermission(roleId, menuId);
	}

	public void deleteMenu(String menuId) {
		securityDao.deleteMenu(menuId);
	}

	public void deletePermission(String permissionId) {
		securityDao.deletePermission(permissionId);
	}

	public void deleteResource(String idString) {
		String[] ids = idString.split(",");
		for (int i = 0; i < ids.length; i++) {
			securityDao.deleteReource(ids[i]);
		}
	}

	public void deleteRole(String idString) {
		String[] ids = idString.split(",");
		for (int i = 0; i < ids.length; i++) {
			securityDao.deleteRole(ids[i]);
		}
	}

	public void filterResource(Resource resource, Page<Resource> page) {
		securityDao.filterResource(resource, page);
	}

	public List<AsyncTreeNode> loadPermissionTree(String roleId) {
		List<AsyncTreeNode> nodes = new ArrayList<AsyncTreeNode>();
		List<Menu> menus = securityDao.queryAllMenu();
		Map<String, AsyncTreeNode> nodeMap = new HashMap<String, AsyncTreeNode>();
		for (Menu menu : menus) {
			AsyncTreeNode node = new AsyncTreeNode();
			node.setId(menu.getId());
			node.setText(menu.getName());
			node.setLeaf(false);
			if (nodeMap.get(menu.getParentId()) == null) {
				nodes.add(node);
			}
		}
		return nodes;
	}

	public List<Resource> loadResource(int resourceId) {
		List<Resource> list = null;
		if (resourceId == 0) {
			list = securityDao.loadResource();
		} else {
			list = securityDao.loadResourceById(resourceId);
		}
		return list;
	}

	public List<Resource> loadResource(Resource resource) {
		List<Resource> list = null;
		if (resource == null || resource.getResourceId() == 0) {
			list = securityDao.loadResource();
		} else {
			list = securityDao.loadResourceById(resource.getResourceId());
		}
		return list;
	}

	public void loadResource(Resource resource, Page<Resource> page) {
		if (resource == null) {
			securityDao.loadResource(page);
		} else {
			securityDao.loadResource(resource, page);
		}

	}

	public List<Role> loadRole(Role role, Page<Role> page) {
		List<Role> list = null;
		if (role == null) {
			list = securityDao.loadRole(page);
		} else {
			list = securityDao.loadRole(role.getId());
		}
		return list;
	}

	public List<Role> loadRole(String roleId) {
		return securityDao.loadRole(roleId);
	}

	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,
			DataAccessException {
		User user = securityDao.queryUserByUsername(username);
		List<Authority> auths = securityDao.queryAuthsByUsername(username);
		GrantedAuthority[] ga = new GrantedAuthority[auths.size()];
		for (int i = 0; i < auths.size(); i++) {
			ga[i] = new GrantedAuthorityImpl((auths.get(i)).getName());
		}
		org.springframework.security.userdetails.User userdetail = new org.springframework.security.userdetails.User(
				user.getUsername(), user.getPassword(), true, true, true, true, ga);
		return userdetail;
	}

	public User loadUser(String username, String password) {
		User user = securityDao.queryUserByUsername(username);
		if (user != null && !password.equals(user.getPassword())) {
			user = null;
		}
		return user;
	}

	public User loadUser(User u) {
		User user = securityDao.queryUserByUsername(u.getUsername());
		if (user != null && !u.getPassword().equals(user.getPassword())) {
			user = null;
		}
		return user;
	}

	public List<Permission> queryCheckedPermission(String roleId, String menuId) {
		return securityDao.queryCheckedPermission(roleId, menuId);
	}

	public Menu queryMenuInfo(String id) {
		return securityDao.queryMenuInfo(id);
	}

	public Permission queryPermissionInfo(String id) {
		return securityDao.queryPermissionInfo(id);
	}

	public List<Resource> queryPermissionResource(String permissionId) {
		return securityDao.queryPermissionResource(permissionId);
	}

	public List<Map<String, Object>> queryRequestMap() {
		return securityDao.queryRequestMap();
	}

	public List<AsyncTreeNode> querySubMenus(String id) {
		return securityDao.querySubMenus(id);
	}

	public List<AsyncTreeNode> querySubMenusForPermission(String id) {
		return securityDao.querySubMenusForPermission(id);
	}

	public List<AsyncTreeNode> querySubPermissions(String id) {
		return securityDao.queryUserFunctions(id);

	}

	public List<Permission> queryUncheckedPermission(String roleId, String menuId) {
		return securityDao.queryUncheckedPermission(roleId, menuId);
	}

	public List<Resource> queryUncheckedResource(String permissionId) {
		List<Resource> all = securityDao.loadResource();
		List<Resource> checked = securityDao.queryPermissionResource(permissionId);
		List<Resource> unchecked = new ArrayList<Resource>();
		for (Resource res : all) {
			boolean flag = true;
			for (Resource resource : checked) {
				if (resource.getResourceId() == res.getResourceId()) {
					flag = false;
				}
			}
			if (flag) {
				unchecked.add(res);
			}
		}
		return unchecked;
	}

	public List<Resource> queryUncheckedResource(String permissionId, String query) {
		List<Resource> all = null;
		if (query != null && !query.equals("")) {
			all = securityDao.searchResource(query);
		} else {
			all = securityDao.loadResource();
		}
		List<Resource> checked = securityDao.queryPermissionResource(permissionId);
		List<Resource> unchecked = new ArrayList<Resource>();
		for (Resource res : all) {
			boolean flag = true;
			for (Resource resource : checked) {
				if (resource.getResourceId() == res.getResourceId()) {
					flag = false;
				}
			}
			if (flag) {
				unchecked.add(res);
			}
		}
		return unchecked;
	}

	public List<Resource> searchResource(String search) {
		return securityDao.searchResource(search);

	}

	public void searchResource(String query, Page<Resource> page) {
		securityDao.searchResource(query, page);
	}

	public List<Role> searchRole(String query, Page<Role> page) {
		return securityDao.searchRole(query, page);
	}

	public void updateMenu(Menu menu) {
		if (menu.getId() != null && !menu.getId().equals("")) {
			securityDao.updateMenu(menu);
		} else {
			String maxId = securityDao.queryLastSubMenuId(menu.getParentId());
			if (maxId == null || maxId.equals("")) {
				maxId = menu.getParentId() + "_000";
			}
			String index = "000" + (Integer.parseInt(maxId.substring(maxId.length() - 3)) + 1);
			menu.setId(maxId.substring(0, maxId.length() - 4) + '_'
					+ index.substring(index.length() - 3));
			securityDao.addMenu(menu);
		}

	}

	public void updatePermission(Permission permission) {
		if (permission.getId() != null && !permission.getId().equals("")) {
			securityDao.updatePermission(permission);
		} else {
			securityDao.addPermission(permission);
		}

	}

	public void updatePermissionResource(String permissionId, String[] resourceIds) {
		securityDao.deletePermissionResource(permissionId);
		for (String id : resourceIds) {
			if (!id.equals("")) {
				securityDao.addPermissionResource(permissionId, id);
			}
		}
	}

	public void updateResource(Resource resource) {
		if (resource.getResourceId() != 0) {
			securityDao.updateReource(resource);
		} else {
			securityDao.addResource(resource);
		}
	}

	public void updateRole(Role role) {
		if (StringUtils.isEmpty(role.getId())) {
			securityDao.addRole(role);
		} else {
			securityDao.updateRole(role);
		}

	}

	public void updateRolePermission(String roleId, String menuId, String[] userFunctionNames) {
		securityDao.deleteRolePermission(roleId, menuId);
		for (String string : userFunctionNames) {
			securityDao.addRolePermission(roleId, string);
		}
	}

	public void updateRolePermissionAll(String roleId, String menuId) {
		securityDao.deleteRolePermission(roleId, menuId);
		securityDao.addRolePermissionAll(roleId, menuId);
	}

}
